home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / presto / presto10.lha / src / spinlock_impl.h < prev    next >
C/C++ Source or Header  |  1991-12-11  |  4KB  |  167 lines

  1. #ifndef __spinlock_impl_h__
  2. #define __spinlock_impl_h__
  3.  
  4. // Spinlock inline implementations
  5. // Must follow defs for threads, but precede everything else.
  6. //
  7. // Modification History:
  8. //
  9. // 28-Dec-1989  JEF
  10. // Add class HC_Spinlock (for sequent symmetry only).  This variation of
  11. // a spinlock works well when there is high contention for the lock.
  12. // After original by raj.
  13. //
  14. #if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
  15.  
  16. /*
  17.  * Optimized version of S_LOCK to only make the procedure call
  18.  * if the lock is held.  Would really like to use S_LOCK here,
  19.  * but (potentially) inline functions can't handle loops.
  20.  */
  21.  
  22. SPINLOCK_INLINE 
  23. void
  24. Spinlock::lock()
  25. {
  26. #ifdef    ns32000
  27.     char    *lock_alm = &_alm_base[ALM_HASH(sl_lock)]; 
  28. #endif
  29.  
  30.     //
  31.     // Must mark ourselves in the lock even before we acquire it.
  32.     // Otherwise, we could hold the lock and be preempted.  If we
  33.     // were holding the lock on something that the preemption code
  34.     // needed (or someone else, in order to ensure we run), we would
  35.     // deadlock.  Must make lock acquisition and thread in spin cs
  36.     // marking atomic.
  37.     //
  38.  
  39. #ifndef NO_PREEMPT
  40.     thisthread->holdingspinlock();
  41. #endif /*  NO_PREEMPT */
  42.  
  43. #ifdef ns32000
  44.     if (sl_lock == L_LOCKED)        // u lose
  45.         (void)s_lock(&sl_lock);
  46.     else if (*lock_alm & ALM_LOCKED)    // u lose
  47.         (void)s_lock(&sl_lock);
  48.     else if (sl_lock == L_LOCKED) {        // u lose (race condition)
  49.         *lock_alm = ALM_UNLOCKED;
  50.         (void)s_lock(&sl_lock);
  51.     } else    {                // u win
  52.         sl_lock = L_LOCKED;
  53.         *lock_alm = ALM_UNLOCKED;
  54.     }
  55. #else
  56.     //
  57.     // No ALM's in Symmetry.  We use S_LOCK() and to avoid
  58.     // another out-of-line call.  Since C++ doesn't understand
  59.     // asm-functions, must use "CC +hasmdefs.h".
  60.     //
  61.     // On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
  62.     // Should probably be inline.
  63.     //
  64. //cout << "regular old spinlock.lock\n"; cout.flush ();
  65. #ifdef PROFILE
  66.     SLLock(sl_q);
  67. #endif
  68.     (void) S_LOCK(&sl_lock);
  69. #endif
  70. }
  71.  
  72.  
  73. SPINLOCK_INLINE
  74. void
  75. Spinlock::unlock()
  76. {
  77.  
  78. //cout << "regular old spinlock.unlock\n"; cout.flush ();
  79.     (void) S_UNLOCK(&sl_lock);
  80. #ifdef PROFILE
  81.     SLUnlock(sl_q);
  82. #endif
  83. #ifndef NO_PREEMPT
  84.     thisthread->releasingspinlock();
  85. #endif /*  NO_PREEMPT */
  86.  
  87. }
  88.  
  89. SPINLOCK_INLINE
  90. Spinlock::~Spinlock()
  91. {
  92.     //
  93.     // We should abort if the lock is not free. (?) XXX
  94.     // For now just unlock it for backward compatibility.
  95.     //
  96.     if (testlock())
  97.         unlock();
  98. #ifdef PROFILE
  99.     SLDispose(sl_q);
  100. #endif
  101.         
  102. }
  103.  
  104.  
  105. #endif /* DO_SPINLOCK_INLINE || SPINLOCK_C */
  106.  
  107.  
  108.  
  109. //
  110. //  HC_Spinlock inline implementations.
  111. //
  112. #ifdef i386
  113.  
  114. SPINLOCK_INLINE 
  115. void
  116. HC_Spinlock::lock()
  117. {
  118.     //
  119.     // Must mark ourselves in the lock even before we acquire it.
  120.     // Otherwise, we could hold the lock and be preempted.  If we
  121.     // were holding the lock on something that the preemption code
  122.     // needed (or someone else, in order to ensure we run), we would
  123.     // deadlock.  Must make lock acquisition and thread in spin cs
  124.     // marking atomic.
  125.     //
  126. #ifndef NO_PREEMPT
  127.     thisthread->holdingspinlock();
  128. #endif /*  NO_PREEMPT */
  129.  
  130.     //
  131.     // HC_S_LOCK is an inline straight C asm function defined in
  132.     // hc_slock_asm.h, which is pulled into the C++ C output via
  133.     // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
  134.         //
  135. //cout << "high contention spinlock.lock\n"; cout.flush ();
  136. #ifdef PROFILE
  137.     SLLock(sl_q);
  138. #endif
  139.     (void) HC_S_LOCK(&sl_lock);
  140. }
  141.  
  142.  
  143. inline
  144. void
  145. HC_Spinlock::unlock()
  146. {
  147.     //
  148.     // HC_S_UNLOCK is an inline straight C asm function defined in
  149.     // hc_slock_asm.h, which is pulled into the C++ C output via
  150.     // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
  151.         //
  152.  
  153. //cout << "high contention spinlock.unlock\n"; cout.flush ();
  154.  
  155.     (void) HC_S_UNLOCK(&sl_lock);
  156. #ifdef PROFILE
  157.     SLUnlock(sl_q);
  158. #endif
  159.  
  160. #ifndef NO_PREEMPT
  161.     thisthread->releasingspinlock();
  162. #endif /*  NO_PREEMPT */
  163. }
  164.  
  165. #endif /* i386 */
  166. #endif /* __spinlock_impl_h__ */
  167.